<?php
namespace Budget\BudgetBundle\Services;

use Budget\BudgetBundle\Entity\Family;
use Doctrine\ORM\EntityManager;
use Budget\BudgetBundle\Helper\DateHelper;
use Budget\BudgetBundle\Helper\FamilyHelper;

class ExpenseService
{
    protected $entityManager;
    
    public function __construct(EntityManager $entityManager) {
        $this->entityManager = $entityManager;
    }
    
    public function getExpensesForFamilyToArray(Family $family, $page = '1', $limit = '-1', $sidx = 'e.date', $sord = 'desc', $where = "")
    {
        if (!$sidx) {
            $sidx = 1;
        }
   
        if (!$where) {
            $startDateStr = FamilyHelper::getStartMonthDbStr($family);
            $endDateStr   = FamilyHelper::getEndMonthDbStr($family);
            $whereSQL     = " AND e.date >= '" . $startDateStr."' AND e.date <= '" . $endDateStr . "'";
        } else { 
            //$whereSQL = $where['where'];     
            $whereSQL = '';        
        }
            
        $qb = $this->entityManager->getRepository('BudgetBudgetBundle:Expense')->getExpensesForFamilyToArrayQuery($family, $sidx, $sord, $whereSQL);           
        
     
        if ($where) {
            for ($i=0; $i<count($where['parameters']); $i++) {
                $qb->andWhere($where['where'][$i]);
                $qb->setParameter($where['parameters'][$i]['name'], $where['parameters'][$i]['val']);
            }
        }
  
        return  $qb->getQuery()->getArrayResult();  
    }
    
    public function getTotalSumExpensesForFamily(Family $family, $dateTo, $dateFrom, $categories)
    {      
        if (!$dateTo) {
            $dateTo = date(DateHelper::FORMAT_YEAR_MONTH);
        } else {
            $dateTo = DateHelper::convertToYearMonth($dateTo);
        }
       
        if (!$dateFrom) {
            $dateFrom = date(DateHelper::FORMAT_YEAR_MONTH);
        } else {
            $dateFrom = DateHelper::convertToYearMonth($dateFrom);
        }

        $qb = $this->entityManager->getRepository('BudgetBudgetBundle:Expense')->getTotalSumExpensesForFamilyQuery($family, $dateFrom.'-01 '.DateHelper::DAY_START, $dateTo.'-31 '.DateHelper::DAY_END);           
        
        if($categories[0]) {
            $qb->andWhere('c.id IN (:categories)' );
            $qb->setParameter('categories', array_values($categories));
        }
        $result = $qb->getQuery()->getSingleResult();

        return  $result;  
    }
    
    public function getFormatPlannedExpensesToJson($expenses)
    {       
        $response            = array();
        $response['page']    = 1;
        $response['total']   = 1;
        $response['records'] = count($expenses);

        foreach ($expenses AS $expense) { 
            $gridClass = 'redGridRow';
            if($expense['date_execution']) {
                $gridClass = 'greenGridRow';
            }
            $response['rows'][] = array(
                'id' => $expense['id'],
                'cell' => array(
                    $expense['id'],
                    $expense['category']['name'],
                    $expense['amount'],
                    $expense['name'],
                    $expense['date_expired']->format(DateHelper::FORMAT_USER),                   
                    $gridClass                   
                )
             );
        } 
        return $response;
    }
    
    public function formatPlannedExpensesAsInitialData(array $expenses)
    {       
        $response            = array();
        
        if (empty($expenses)) {
            return $response;
        }
        
        foreach ($expenses AS $expense) { 
            $response[] = array(
                'id'            => $expense['id'],
                'category'          => $expense['category']['name'],
                'amount'        => $expense['amount'],
                'name'          => $expense['name'],
                'date_expired'  => $expense['date_expired']->format(DateHelper::FORMAT_USER),                   
                'class'         => $expense['date_execution']? 'greenGridRow': 'redGridRow'                   
             );
        } 
        
        return $response;
    }
    
    public function getFormatExpensesToJson($expenses)
    {       
        $response            = array();
        $response['page']    = 1;
        $response['total']   = 1;
        $response['records'] = count($expenses);

        foreach ($expenses AS $expense) {  
            $response['rows'][] = array(
                'id' => $expense['id'], 
                'cell' => array(
                    $expense['id'],
                    $expense['category']['name'],
                    $expense['price'],
                    $expense['comment'],
                    $expense['date']->format(DateHelper::FORMAT_USER)
                ) 
             );
        } 
        return $response;
    }
    
    public function formatExpensesAsInitialData(array $expenses)
    {       
        $response = array();
        
        if (empty($expenses)) {
            return $response;
        }
        
        foreach ($expenses as $expense) {  
            $response[] = array(
                'id'        => $expense['id'], 
                'name'      => $expense['category']['name'],
                'price'     => $expense['price'],
                'comment'   => $expense['comment'],
                'date'      => $expense['date']->format(DateHelper::FORMAT_USER)
                
             );
        } 
        
        return $response;
    }
    
    public function getFormatExpensesToChartJson($expenses, $dateTo, $dateFrom)
    {       
        $months = $response = array();
        if ($dateTo >= $dateFrom) {
            $arrayDateFrom = explode('-', $dateFrom);
            $i  = 0;
            $mm = $arrayDateFrom[1];
            $yy = $arrayDateFrom[0];
            while (true) {
                $months[$i]   = $yy.'-'.$mm;
                $response[$i] = array(DateHelper::getMonthName($mm), 0);
                $i++;
                if ($yy.'-'.$mm == $dateTo) {
                    break;
                } else {
                    if ($mm == 12) {
                       $mm  = 1;
                       $yy += 1;
                    } else {
                        $mm += 1;
                    }
                    if($mm < 10) {
                        $mm = '0'.$mm;
                    }
                }
            }
        }
        
        $count = count($months);
        foreach ($expenses AS $expense) {  
            $month = $expense['date']->format(DateHelper::FORMAT_YEAR_MONTH); 
            for($i=0; $i<$count; $i++) {
                if($months[$i] == $month) {
                    break;
                }
            }
            $response[$i][1] = $response[$i][1] + $expense['price'];
        }
        return $response;
    }
    
    public function countTotalAmount(array $expenses, $idx = 'price')
    {
        $amount = 0;
        
        foreach ($expenses as $row) {
            $amount += $row[$idx];
        }
        
        return $amount;
    }
    
    public function groupByMainCategory($expenses)
    {       
        $result = array();
        $total  = 0;
        foreach ($expenses AS $expense) {  
            if (!isset($result[$expense['category']['id']])) {
                $result[$expense['category']['id']] = array(
                    'name' => $expense['category']['name'],
                    'sum'  => 0
                );
            }
            
            $result[$expense['category']['id']]['sum'] += $expense['price'];
            $total += $expense['price'];
        } 
        
        uasort($result, array($this, 'sortGrouped')); 
        $result[0] = array('name' => 'Razem', 'sum' => $total);
        
        return $result;
    }
    
    public function sortGrouped($a, $b)
    {
        if ($a['sum'] == $b['sum']) {
            return 0;
        }
        
        return ($a['sum'] > $b['sum'] ) ? -1 : 1;
    }
}

